<template>
  <div class="designer" v-loading="template.loading" element-loading-text="检验模板加载中,请稍后..." element-loading-spinner="el-icon-loading">
    <div class="container">
      <div class="editorArea">
        <div class="editor-canvas" v-if="dataJson.rows && dataJson.rows.length > 0">
          <div class="grid-canvas" :style="canvasStyle">
            <table ref="tableDom" border="1" cellspacing="0" cellpadding="0" :style="computedTableStyle">
              <colgroup>
                <col :style="{ width: (item.width || baseTableConfig.cellWidth) + 'px' }" v-for="(item, index) in xAxisNum" :key="item" />
              </colgroup>
              <tr v-for="(item, index) in tablePreviewData" :key="index">
                <td
                  v-for="(cItem, cIndex) in computedNotHide(item.cells)"
                  :key="cIndex"
                  :x="cItem.x"
                  :y="cItem.y"
                  :class="['tdCell', cItem.isEdit ? 'active' : '', cItem.checkField ? 'checkField' : '', cItem.apiField ? 'apiField' : '']"
                  :style="computedTdStyle(cItem.style)"
                  :rowspan="cItem.merge && cItem.merge.length == 2 ? cItem.merge[0] : 1"
                  :colspan="cItem.merge && cItem.merge.length == 2 ? cItem.merge[1] : 1"
                >
                  <!-- 文本类型 只展示 -->
                  <template v-if="cItem.type == 'text' && !cItem.isEdit">{{ cItem.value }}</template>
                  <!-- 动态展示组件 -->
                  <component
                    v-else
                    :ref="cItem.x + '-' + cItem.y + '-comp'"
                    :is="formatterCompType(cItem.type)"
                    :tdStyle="computedComponentStyle(cItem.style)"
                    :value="cItem.value"
                    :dicData="cItem.dicData"
                  />
                </td>
              </tr>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { propertyList } from './property.js';
import request from '@/router/axios';
import { isClickSameCell } from './util.js';
import boxArea from './boxArea.vue';
import contextMenu from './contextMenu.vue';
import menuBtnGroups from './menuBtnGroups.vue';
import fieldList from './fieldList.vue';
import attrConfig from './attrConfig.vue';
import { mapGetters, mapState } from 'vuex';

import shdFormDesignText from './components/input.vue';
import shdFormDesignNumber from './components/inputNumber.vue';
import shdFormDesignRadio from './components/radio.vue';
import shdFormDesignCheckbox from './components/checkbox.vue';
import shdFormDesignSelect from './components/select.vue';
import shdFormDesignBtnAddRow from './components/btnAddRow.vue';
import shdFormDesignBtnDeleteRow from './components/btnDeleteRow.vue';

export default {
  name: 'SHDFormDesigner',
  components: {
    boxArea,
    menuBtnGroups,
    contextMenu,
    fieldList,
    attrConfig,
    'shdFormDesign-text': shdFormDesignText,
    'shdFormDesign-number': shdFormDesignNumber,
    'shdFormDesign-radio': shdFormDesignRadio,
    'shdFormDesign-checkbox': shdFormDesignCheckbox,
    'shdFormDesign-select': shdFormDesignSelect,
    'shdFormDesign-btnAddRow': shdFormDesignBtnAddRow,
    'shdFormDesign-btnDeleteRow': shdFormDesignBtnDeleteRow
  },
  props: {
    liveParams: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      tablePreviewData: [],
      fieldsMap: {},
      template: {
        loading: false
      },
      startXGuide: 0,
      changeXAxisIndex: -1,
      xSublineGuideLeft: 0,
      showXSubline: false,
      showXSublineGuide: false,
      tooltip: {
        color: '',
        bgcolor: '',
        fontSize: 12,
        'font-weight': ['bold', 'normal'],
        'font-style': ['italic', 'normal'],
        'text-decoration': ['underline', 'none']
      },
      rules: {
        rows: [{ required: true, message: '请输入行数', trigger: 'change' }],
        columns: [{ required: true, message: '请输入列数', trigger: 'change' }]
      },
      contextMenu: {
        top: 0,
        left: 0
      },
      startX: '',
      startY: '',
      moveX: '',
      moveY: '',
      oldMoveX: '',
      oldMoveY: '',
      boxStyle: {
        width: 0,
        height: 0,
        top: 0,
        left: 0
      },
      showBoxArea: false,
      showContextMenu: false,
      propertyList: propertyList
    };
  },
  computed: {
    ...mapState({
      cellInfo: (state) => state.form.cellInfo,
      dataJson: (state) => state.form.dataJson,
      apiJson: (state) => state.form.apiJson,
      histroyData: (state) => state.form.histroyData,
      histroyIndex: (state) => state.form.histroyIndex,
      baseTableConfig: (state) => state.form.baseTableConfig,
      boxAreaXY: (state) => state.form.boxAreaXY,
      xAxisNum: (state) => state.form.xAxisNum,
      yAxisNum: (state) => state.form.yAxisNum
    }),
    canvasStyle() {
      // +1修复表格边框线重叠问题导致X轴换行
      let xLen =
        this.xAxisNum.reduce((pre, cur) => {
          return pre + cur.width;
        }, 50) + 1;
      let yLen = this.yAxisNum.reduce((pre, cur) => {
        return pre + cur.height;
      }, this.baseTableConfig.cellHeight);
      return {
        width: xLen + 'px',
        height: yLen + 'px'
      };
    },
    computedTableStyle() {
      if (this.dataJson.tableTotalWidth) {
        return {
          width: this.dataJson.tableTotalWidth + 'px'
        };
      }
    },
    computedTdStyle(style) {
      return (style) => {
        return {
          ...style,
          'font-size': (style['font-size'] || 12) + 'px',
          height: (style.height || this.baseTableConfig.cellHeight) - 1 + 'px'
          // 'line-height': (style.height || this.baseTableConfig.cellHeight) - 1 + 'px'
        };
      };
    },
    computedComponentStyle(style) {
      return (style) => {
        return {
          width: (style.width || this.baseTableConfig.cellWidth) - 1 + 'px',
          'font-size': (style['font-size'] || 12) + 'px',
          height: (style.height || this.baseTableConfig.cellHeight) - 1 + 'px',
          'line-height': (style.height || this.baseTableConfig.cellHeight) - 1 + 'px'
        };
      };
    },
    formatterCompType(type) {
      return (type) => {
        return 'shdFormDesign-' + (type || 'text');
      };
    },
    isNotSameCell() {
      return isClickSameCell(this.boxAreaXY.startX, this.boxAreaXY.startY, this.boxAreaXY.endX, this.boxAreaXY.endY);
    }
  },
  beforeDestroy() {
    this.$store.commit('form/clearDesignerData');
  },
  methods: {
    async handlePreviewApi() {
      const that = this;
      if (that.dataJson.id) {
        // 渲染检验单
        that.template.loading = true;
        let data = await that.$store.dispatch('form/getFormTemplate', {
          id: that.dataJson.id
        });
        // 置空检验项
        let apiJson = JSON.parse(data.apiJson || '[]');
        await that.handleApi(apiJson);
      }
    },
    ajax(item, prePromise) {
      const that = this;
      return new Promise((resolve, reject) => {
        let route = Object.assign({}, that.liveParams);
        let query = {
          apiCode: item.showQuery.apiCode,
          parameterDatas: item.paramsForm
        };
        if (item.paramsForm && item.paramsForm.length > 0) {
          item.paramsForm.forEach((pItem) => {
            let reg = /#{|}/g;
            let pItemValue = pItem.value.replace(reg, '');
            let [apiCode, param] = pItemValue.split('.');
            prePromise.map((rItem) => {
              if (rItem.key == apiCode) {
                pItem.value = rItem.params[param];
              }
            });
          });
          query.parameterDatas = structuredClone(item.paramsForm);
          queryData(item.url, query);
        } else {
          // 没有依赖参
          for (const key in route) {
            if (query.parameterDatas.length > 0) {
              query.parameterDatas.map((p) => {
                if (p.code == key) {
                  p.value = route[key];
                }
              });
            } else {
              query.parameterDatas.push({
                code: key,
                value: route[key]
              });
            }
          }
          queryData(item.url, query);
        }

        function queryData(url, query, method = 'POST') {
          console.log('query', query);
          request({
            url,
            method,
            data: query
          })
            .then((result) => {
              let data = result.data.data;
              if (Array.isArray(data)) {
                resolve({
                  key: item.code,
                  params: data[0]
                });
              } else {
                resolve({
                  key: item.code,
                  params: data
                });
              }
            })
            .catch((err) => {
              reject(err);
            });
        }
      });
    },
    // 串行处理api
    async handleApi(data) {
      const that = this;
      try {
        let resultList = await data.reduce(async (promiseChain, cur) => {
          const previousResults = await promiseChain;
          const currentResult = await that.ajax(cur, previousResults);
          return [...previousResults, currentResult];
        }, Promise.resolve([]));
        console.log(resultList, 'resultList');
        for (const item of resultList) {
          let code = item.key;
          if (item.params && Object.keys(item.params).length > 0) {
            for (const key in item.params) {
              that.fieldsMap[`#{${code}.${key}}`] = item.params[key];
            }
          } else {
            that.fieldsMap = {};
          }
        }
        that.tablePreviewData = structuredClone(that.dataJson.rows);
        that.tablePreviewData.forEach((item) => {
          item.cells.forEach((cItem) => {
            if (cItem.code) {
              if (typeof cItem.code == 'string') {
                cItem.code = cItem.code.trim();
              }
              if (that.fieldsMap[cItem.code]) {
                cItem.value = that.fieldsMap[cItem.code];
              }
            }
          });
        });
        console.log(that.fieldsMap);
      } catch (error) {
        console.log(error);
      } finally {
        that.template.loading = false;
      }
    },
    computedNotHide(cell) {
      return cell.filter((item) => !item.hide);
    }
  }
};
</script>
<style scoped lang="scss">
.designer {
  .container {
    position: relative;
    height: calc(100vh - 150px);
    background-color: #fff;

    .editorArea {
      position: absolute;
      left: 0;
      width: 100%;
      height: 100%;
      .editor-canvas {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        overflow: auto;
        .grid-canvas {
          width: 100%;
          height: 100%;
          position: relative;

          table {
            position: absolute;
            table-layout: fixed;
            border-collapse: collapse;
            word-break: break-all;
            word-wrap: break-word;
            border-width: 0;
            tr {
              td {
                background-color: #fff;
                user-select: none;
                text-align: center;
                position: relative;

                ::v-deep .el-input__inner {
                  background: #fff;
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>
